package com.baidu.config;
import com.baidu.model.Cron;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.baidu.util.*;
import com.jfinal.log.Log;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 定时任务管理
 * @author libs
 * 2015-12-4 15:34
 */
public class QuartzManager{
    private final Log log = Log.getLog(getClass());
	private static Map<Job, Cron> jobs = Maps.newLinkedHashMap();
    private SchedulerFactory sf;
    private Scheduler scheduler;
    
    /**
     * 初始化所有任务
     * @throws SecurityException 
     * @throws NoSuchMethodException 
     */
    public static void initAllJobs(){
    	List<Cron> jobList = Cron.dao.queryAllJobs();
    	for (Cron cron : jobList) {
    		Job job = Reflect.on(cron.getStr("className")).create().get();
    		jobs.put(job, cron);
		}
    }
    
    public QuartzManager() {
    	initAllJobs();
	}
    
    //添加任务
	public QuartzManager add(Cron cron, Job job) {
        jobs.put(job, cron);
        return this;
    }
	
	//移除任务
	public QuartzManager remove(Job job) {
        jobs.remove(job);
        return this;
    }
	
	//启动任务
    public boolean start() {
        startJobs();
        return true;
    }
    
    //停止任务
    public boolean stop() {
        try {
            scheduler.shutdown();
        } catch (SchedulerException e) {
            Throwables.propagate(e);
        }
        return true;
    }
    
    private void startJobs() {
        try {
            sf = new StdSchedulerFactory();
            scheduler = sf.getScheduler();
        } catch (SchedulerException e) {
            Throwables.propagate(e);
        }
        Set<Map.Entry<Job, Cron>> set = jobs.entrySet();
        for (Map.Entry<Job, Cron> entry : set) {
            Job job = entry.getKey();
            String jobClassName = job.getClass().getName();
            Cron cron = entry.getValue();
            String jobCronExp = cron.getStr("cronExpression");
            JobDetail jobDetail;
            CronTrigger trigger;
            jobDetail = Reflect.on("org.quartz.JobBuilder").call("newJob", job.getClass()).call("withIdentity", jobClassName, jobClassName)
                    .call("build").get();
            jobDetail.getJobDataMap().put("cronType", cron.getInt("code"));//任务类型
            Object temp = Reflect.on("org.quartz.TriggerBuilder").call("newTrigger").get();
            temp = Reflect.on(temp).call("withIdentity", jobClassName, jobClassName).get();
            temp = Reflect.on(temp).call("withSchedule",
                    Reflect.on("org.quartz.CronScheduleBuilder").call("cronSchedule", jobCronExp).get())
                    .get();
            trigger = Reflect.on(temp).call("build").get();
            Date ft = Reflect.on(scheduler).call("scheduleJob", jobDetail, trigger).get();
            log.debug(Reflect.on(jobDetail).call("getKey") + " has been scheduled to run at: " + ft + " " +
                    "and repeat based on expression: " + Reflect.on(trigger).call("getCronExpression"));
        }
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            Throwables.propagate(e);
        }
    }

}
